# GPL3 or any later version

import os
import json
import time

import gi
import threading
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GLib

from modules import wallet
from modules import items
from modules import merchants
from modules import ui
from modules import totals

def add(win):

    # This is a transaction adder

    the_wallet = win.wallet
    
    folder = wallet.save_folder()+"wallets/"+the_wallet+"/transactions/"
    try:
        os.makedirs(folder)
    except:
        pass
    name = str(int(time.time()))+".json"
    editor(win, name)
    
def editor(win, name):

    # This is a transaction editor
    
    the_wallet = win.wallet
    folder = wallet.save_folder()+"wallets/"+the_wallet+"/transactions/"
    tfile = folder+name
    
    dialogWindow = Gtk.Dialog("Transaction",
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                     Gtk.STOCK_OK, Gtk.ResponseType.OK),
        )
    dialogWindow.set_size_request(400, 400)
    
    box = dialogWindow.get_content_area()

    # Loading transaction data
    try:
        with open(tfile) as json_file: 
            data = json.load(json_file)
    except:
        data = {}

    scrl = Gtk.ScrolledWindow()
    scrl.set_vexpand(0)
    box.pack_start(scrl, 1,1,1)

    pack = Gtk.VBox()
    scrl.add(pack)

    refresh_editor(win, pack, data)

    


    box.show_all()
    
    response = dialogWindow.run()
    if response == Gtk.ResponseType.OK:

        data["total"] = 0
        for i in data.get("items", []):
            data["total"] = data["total"] + (i.get("amount",0)*i.get("price"))
        
        with open(tfile, "w") as fp:
            json.dump(data, fp, indent=4)

        update_transactions(win)
        totals.update_totals(win)

    dialogWindow.destroy()

def refresh_editor(win, pack, data):

   
    for i in pack.get_children():
        i.destroy()

    totals = wallet.get_totals(win.wallet)
    currancy = totals.get("currancy", "$")

    
    if not data.get("merchant"):

        def do_add_merchant(w):

            merchant = merchants.select_dialogue(win,mode="transaction_add")
            data["merchant"] = merchant
            refresh_editor(win, pack, data)
            
        add_merchant = Gtk.Button()
        add_merchant.set_relief(Gtk.ReliefStyle.NONE)
        add_box = Gtk.HBox()
        add_merchant.add(add_box)
        add_box.pack_start(ui.icon(win,"list-add"),0,0,0)
        add_box.pack_start(Gtk.Label("Add Merchant"),1,1,1)
        add_merchant.connect("clicked", do_add_merchant)
        pack.pack_start(add_merchant, 0,0,0)

    else:
        folder = wallet.save_folder()+"merchants/"
        mfile = folder+str(data.get("merchant"))
        with open(mfile) as json_file: 
            mdata = json.load(json_file) 

        merchant_box = Gtk.HBox()
        pack.pack_start(merchant_box, 0,1,1)

        save_as = mdata.get("image", "")
        if os.path.exists(save_as):
            image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
        else:
            image = ui.icon(win, "go-home")

        merchant_box.pack_start(image, 0,0,0)

        mtext_box = Gtk.VBox()
        merchant_box.pack_start(mtext_box, 1,1,1)

        def on_delete(w):
            try:
                del data["merchant"]
            except:
                pass
            refresh_editor(win, pack, data)
        
        delete_button = Gtk.Button()
        delete_button.connect("clicked", on_delete)
        delete_button.set_relief(Gtk.ReliefStyle.NONE)
        delete_button.add(ui.icon(win, "process-stop", size=Gtk.IconSize.SMALL_TOOLBAR))
        delete_box = Gtk.HBox()
        delete_box.pack_end(delete_button, 0,0,0)
        mtext_box.pack_start(delete_box, 0,0,0)

        
        mtext_box.pack_start(Gtk.Label(str(mdata.get("name"))), 0,0,0)
        mtext_box.pack_start(Gtk.Label(str(mdata.get("address"))), 0,0,0)


    # Items

    flowbox = Gtk.FlowBox()
    flowbox.set_valign(Gtk.Align.START)
    flowbox.set_max_children_per_line(30)
    flowbox.set_selection_mode(Gtk.SelectionMode.NONE)

    
    def do_add_item(w):
        item = items.select_dialogue(win, mode="transaction_add")
        if "items" not in data:
            data["items"] = []
        if type(item) == dict:
            data["items"].append(item)
        refresh_editor(win, pack, data)


    add_item = Gtk.Button()
    add_item.add(ui.icon(win,"list-add"))
    add_item.set_relief(Gtk.ReliefStyle.NONE)
    flowbox.add(add_item)
    add_item.connect("clicked", do_add_item)
        
    folder = wallet.save_folder()+"items/"

    total = 0
    
    for n, i in enumerate(data.get("items", [])):
        
        try:
            with open(folder+i.get("item")+".json") as json_file: 
                idata = json.load(json_file)
        except:
            idata = {}

        item_box = Gtk.VBox()
        flowbox.add(item_box)

        
        save_as = idata.get("image", "")
        if os.path.exists(save_as):
            image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
        else:
            image = ui.icon(win, "package-x-generic")

        image_box = Gtk.HBox()
        image_box.pack_start(image, 1,1,1)

        def on_delete(w, n):
            try:
                del data["items"][n]
            except:
                pass
            refresh_editor(win, pack, data)
        
        delete_button = Gtk.Button()
        delete_button.connect("clicked", on_delete, n)
        delete_button.set_relief(Gtk.ReliefStyle.NONE)
        delete_button.add(ui.icon(win, "process-stop", size=Gtk.IconSize.SMALL_TOOLBAR))
        delete_box = Gtk.VBox()
        delete_box.pack_start(delete_button, 0,0,0)
        image_box.pack_end(delete_box, 0,0,0)
        
            
        item_box.pack_start(image_box, 0,0,0)
        item_box.pack_start(Gtk.Label(str(idata.get("name", ""))), 0,0,0)
        item_box.pack_start(Gtk.Label(str(i.get("amount", ""))+" x "+currancy+str(i.get("price", ""))), 0,0,0)
        
        total = total + (i.get("amount", 0) * i.get("price", 0))

    
        
    pack.pack_start(flowbox, 1,1,1)


    # Description
    def on_comment(w):
        tb = detext.get_buffer()
        data["comment"] = tb.get_text(tb.get_start_iter(), tb.get_end_iter(), True)
        
    descrl = Gtk.ScrolledWindow()
    descrl.set_size_request(200,200)
    detext = Gtk.TextView()
    detext.get_buffer().connect("changed", on_comment)
    detext.set_wrap_mode(Gtk.WrapMode.WORD)
    detext.get_buffer().set_text(data.get("comment", ""))
    descrl.add(detext)

    pack.pack_end(descrl, 0,0,5)
    pack.pack_end(Gtk.Label("Comment:"), 0,0,5)

    
    # Flip

    def do_flip(w):
        for i in data.get("items", []):
            try:
                i["price"] = i["price"] * -1
            except:
                pass
            
        refresh_editor(win, pack, data)
            
    flip = Gtk.Button()
    flip.set_relief(Gtk.ReliefStyle.NONE)
    flip_box = Gtk.HBox()
    flip_box.pack_start(ui.icon(win, "go-jump"), 0,0,0)
    flip_box.pack_start(Gtk.Label("Flip Transaction"), 1,1,5)
    flip.add(flip_box)
    flip.connect("clicked", do_flip)
    pack.pack_end(flip, 0,0,0)
    
    # TOTAL
   
    total_label = Gtk.Label()
    total_label.set_line_wrap_mode( Gtk.WrapMode.WORD )
    total_label.set_line_wrap(True)
    total_label.set_markup('<span size="x-large">  '+currancy+str(round(total, 2))+'</span> ')
    total_label.set_selectable(True)
    total_label.set_css_name("")

    pack.pack_end(total_label, 1,1,10)


    
    
    

    
    pack.show_all()
    
def update_transactions(win):

    t = wallet.get_totals(win.wallet)
    
    box = win.transactions_box
    
    
    folder = wallet.save_folder()+"wallets/"+win.wallet+"/transactions/"
    
    for i in box.get_children():
        i.destroy()

    try:
        transactions = list(os.walk(folder))[0][2]
        transactions = sorted(transactions)
        transactions = reversed(transactions)
    except:
        transactions = []


        
    for i in transactions:

        with open(folder+i) as json_file: 
            tdata = json.load(json_file)

        def on_tbutton(w, name):
            editor(win, name)
            
        tbutton = Gtk.Button()
        tbutton.set_tooltip_text(tdata.get("comment", ""))
        tbutton.connect("clicked", on_tbutton, i)
        tbutton.set_relief(Gtk.ReliefStyle.NONE)
        tbox = Gtk.HBox()
        tbutton.add(tbox)

        tbox.pack_start(ui.icon(win,"task-past-due"), 0,0,0)

        try:
            tdate = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(int(i.replace(".json", ""))))
                      
        except Exception as e:
            print( e )
            tdate = "[Date Unknown]"

        try:
             mfolder = wallet.save_folder()+"merchants/"
             mfile = mfolder+str(tdata.get("merchant"))
             with open(mfile) as json_file: 
                 mdata = json.load(json_file)
             merchant = mdata.get("name", "")+" "+mdata.get("address", "")
        except Exception as e:
            print( e )
            merchant = "[Private]"

        tbox.pack_start(Gtk.Label(tdate), 0,0,10)
        tbox.pack_start(Gtk.Label(merchant), 1,1,10)
        tbox.pack_end(Gtk.Label(t.get("currancy", "$")+" "+str(round(tdata.get("total", 0), 2))), 0,0,5)
        box.pack_start(tbutton, 0,0,0)

        

    box.show_all()
